import time
import network
import socket
import _misc_util
import os

HEADER='ESP32 HTTPD DEMO'
AP_ESSID='ESP32_HTTPD_DEMO'
AP_AUTHMODE=3
AP_PASSW='aaaa4455'

USE_THREAD=True

if USE_THREAD:
    import _thread
        
def unescape(val):
    if '%' not in val:
        return val
    res=''
    while val:
        if '%' in val:
            pos = val.find('%')
            res+=val[:pos]
            sub = val[pos+1:pos+3]
            res+= chr(int(sub,16))
            val = val[pos+3:]
        else:
            res+=val
            break
    print("unescape: %s" % res)
    return res

def get_html_parms(parms):
    dictx={}
    while parms:
        pos = parms.find('=')
        key = parms[:pos]
        pos2= parms.find('&')
        if pos2>0:
            val = parms[pos+1:pos2]
            parms = parms[pos2+1:]
        else:
            val = parms[pos+1:]
            parms=''
        dictx[key]=unescape(val)
    print('dictx:', dictx)
    return dictx

def start_httpd():
    wlan = setup_sta()
    if wlan is None:
        wlan = setup_ap()
    skip="""
    global var_store
    #horo_main = var_store['horo_main']
    #tft = var_store['tft']
    #info = horo_main.info
    #apname = info['apname']
    #ip = info['ip']
    #tft.fill_rect(20,20,200,100,NAVY)
    #tft.rect(20,20,200,100,LIME)    
    tft.text(apname, 25,30, color=WHITE)
    tft.text(ip, 25,40,color=WHITE)
    tft.text('starting httpd',25,50,color=WHITE)
    """
    if USE_THREAD:

        _thread.start_new_thread(_httpd,())
    else:
        _httpd()

def b2str(bs):
    ss=''
    for x in bs:
        ss+=chr(x)
    return ss


def text_sub_dict(txt, dictx):
    """ at the time of testing, pikapython not support following operation well
    new_txt= txt % dictx
    use this function instead
    """
    new_txt=txt
    for key in dictx:
        item ='%(' + key +')s'
        val = str(dictx[key])
        print('item:', item)
        new_txt = new_txt.replace(item, val)
    return new_txt

def _httpd():
    #addr = socket.getaddrinfo('0.0.0.0',80)[0][-1]
    saddr =("0.0.0.0",80)
    s=socket.socket()
    s.bind(saddr)
    s.listen(1)
    #print('listening on',saddr)
    #tft = var_store['tft']
    #tft.text('httpd listening',25,50,color=WHITE)
    print('httpd listening')    
    #from tfth import get_time, load_tzone, load_geo_cfg
    while True:
        conn,addr = s.accept()
        print("connected from",addr)
        reqb = conn.recv(1024)
        #print("content=%s" % str(reqb))
        req = _misc_util.bytes_to_str(reqb)
        print("req:---\n")
        print(req)
        if reqb==b'':
            continue
        
        if req[:4]=='GET ':
            print('GET')
            pos = req.find(' HTTP/')
            #pos = _misc_util.find_btext(reqb, b' HTTP/')
            if pos>=0:
                cmd = req[4:pos]
                print('cmd:',cmd)
                res = handle_cmd(cmd)
                if res is not None:
                    resp='<html><body>Result: %s<br><br><a href="/">Home</a></body></html>' % res
                    conn.send(resp)
                    conn.close()
                    continue
                
        #tm = get_time()
        #tzone=load_tzone()
        #lat,lon,drx= load_geo_cfg()
        #tm = time.time()+tzone*60*60

        tzone=8
        lat=22
        drx='E'
        lon=114
        tm=0
        ct = time.localtime(tm)
        #yr,mon,mday,hr,minu,sec,wday,_,= ct
        yr,mon,mday,hr,minu,sec,wday,_,= 2023,10,20,11,30,0,5,None
        ds = '%d-%d-%d %02d:%02d:%02d' % (yr,mon,mday,hr,minu,sec)
        dictx={'tms':ds,'yr':yr,'mon':mon,'mday':mday,'hr':hr,'min':minu,'tz':tzone,'lat':lat,'lon':lon,'drx':drx}
        #dictx=add_select(dictx)
        #resp = html % dictx
        f=open('/pikafs/template1.html','r')
        html_1= f.read()
        f.close()
        resp = text_sub_dict(html_1, dictx)
        #print('resp:',resp)
        #resp='<html><body>ok</body></html>'
        conn.send(resp)
        conn.close()

def setup_ap():
    wlan = network.WLAN(network.AP_IF)
    print('setup_ap:%s' % wlan.active())
    if wlan.active():
        wlan.active(False)
    wlan.active(True)
    wlan.config(essid=AP_ESSID)
    wlan.config(authmode=AP_AUTHMODE, password=AP_PASSW)
    ips = wlan.ifconfig()
    print('AP ips:',ips)
    skip="""
    webrepl_pass = setup_webrepl()
    info['HEADER']=HEADER
    info['apname']=AP_ESSID
    info['appass']=PASS
    info['webrepl_pass']=webrepl_pass
    info['ip']=ips[0]
    """
    return wlan

def setup_sta():
    fs = os.listdir('/sd')
    print('fs:',fs)
    if 'ap.dat' not in fs:
        print('no /sd/ap.dat')
        return None

    dictx={}
    f=open('/sd/ap.dat','r')
    cont = f.read()
    f.close()
    lines = cont.split('\n')

    print('lines:',lines)
    for line in lines:
        vs = line.split('=')
        print('vs:', vs)
        key=vs[0]
        dictx[key]=vs[1]

    print('dictx:',dictx)
    if 'apname' not in dictx:
        print('no apname')
        return None
    if 'appass' not in dictx:
        print('no appass')
        return None

    apname = dictx['apname']
    appass = dictx['appass']
    sta = network.WLAN(network.STA_IF)
    sta.active(True)
    sta.connect(apname,appass)
    count=10
    while count > 0:
        if sta.isconnected():
            break
        time.sleep(1);
        count=count -1
        print('wifi trying ', count)
        
    if sta.isconnected():
        ips = sta.ifconfig()
        print('ips:',ips)        
        return sta

    sta.active(False)
    print('connect as sta fail')
    return None

def handle_cmd_set_wifi(parms):
    print('set_wifi: %s' % parms)
    dictx = get_html_parms(parms)
    if dictx['ssid']=='' or len(dictx['pass'])<8:
        return 'Error'
    ss="apname=%s\nappass=%s\n" % (dictx['ssid'], dictx['pass'])
    f=open('/sd/ap.dat','w')
    f.write(ss)
    f.close()
    print("save wifi psw to /sd/ap.dat")
    return 'OK'

def handle_cmd_set_dt(parms):
    dictx = get_html_parms(parms)
    if 'action' not in dictx:
        return 'Error no action'
    try:
        lat =float(dictx['lat'])
        lon= float(dictx['lon'])
    except Exception as e:
        sys.print_exception(e)
        return 'Error geo location'

    drx =dictx['drx']

    yri=int( dictx['yr'])
    moni=int(dictx['mon'])
    mdayi=int(dictx['mday'])
    hri = int(dictx['hr'])
    mini =int(dictx['min'])
    tz =int(dictx['tz'])

    #tmx = time.mktime((yri,moni,mdayi,hri,mini,0,0,0)) - tz*60*60
    #tmy = time.localtime(tmx)
    #yr = tmy[0]
    #mon= tmy[1]
    #mday = tmy[2]
    #hr = tmy[3]
    #minx = tmy[4]
    #wday= tmy[6]
    #jds = hu.ymd_to_jd(yri,moni,mdayi) + hu.hms_to_decday(hri,mini,0) - tz/24.0
    #yr,mon,mday,hr,minx,_=hu.jd_to_ymdhms(jds)
    action=dictx['action']
    if action=='set':
        #from tfth_util import save_tdiff, save_tzone, save_geo_cfg
        #save_tdiff(tmx)
        #save_tzone(tz)
        #save_geo_cfg(lat,lon,drx)
        return 'OK'
    if action=='render':
        #render_horo(tz, yri,moni,mdayi,hri,mini,0,wday,lat,lon,drx)
        return 'Not implemented'
    return 'Invalid action'

def handle_cmd(cmd):
    pos=cmd.find('?')
    cmdx = cmd[:pos]
    print('handle_cmd:%s' % cmdx)
    if cmdx=='/set_wifi':
        return handle_cmd_set_wifi(cmd[pos+1:])
    if cmdx=='/set_dt':
        return handle_cmd_set_dt(cmd[pos+1:])

    return None



